//================================================================
// arguments
function foo(x) {
    console.log(x);  // 10
    for (var i = 0; i < arguments.length; i++) { console.log(arguments[i]); }  // 10, 20, 30
}
foo(10, 20, 30);
//================================================================
// 将函数作为参数
function add(x, y, f) { return f(x) + f(y); }
console.log(add(-5, 6, Math.abs));  // 11
//================================================================
// 另一种定义非匿名参数的方式
var x = function(str) { console.log(arguments.length, arguments[0]);};  // 返回接受参数的个数及内容
x('hello');
//================================================================
// 闭包; 匿名函数自己调用自己
(function() { console.log('hello');})();  // hello;
//================================================================
// 使得函数拥有私有变量变成可能; 计数器受匿名函数的作用域保护, 只能通过 add 方法修改
// 闭包是可访问上一层函数作用域里变量的函数, 即便上一层函数已经关闭
var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}  // 变量 add 指定了函数自我调用的返回字值
})();
add();  // add 变量可以作为一个函数使用. 非常棒的部分是它可以访问函数上一层作用域的计数器.
console.log(add()); // 2
// 类似于面向对象
function myFunction(arg1, arg2) {
    this.firstName = arg1;
    this.lastName = arg2;
}
var x = new myFunction("John", "Doe");
console.log(x.firstName);











